

var EXPORTED_SYMBOLS = ["pm"];

let pm = (function() {
    "use strict";

    const Cu = Components.utils;
    const Ci = Components.interfaces;
    const Cc = Components.classes;
    function require(url) {
        let scope = {};
        Cu.import(url, scope);
        return scope;
    }
    let {MiscUtils} = require("chrome://jsm/content/utils.js");
    let {Prefs} = require("chrome://jsm/content/Preferences.js");
    let {Services} = require("resource://gre/modules/Services.jsm");

    const iMacros_auth_host = "chrome://imacros";
    const iMacros_auth_desc = "iMacros master password";

    return {
        getMasterPwd() {
            let password = this.enquireLoginManager("master");
            
            
            
            if (!password) {
                try {
                    password = Prefs.prefBranch("mastersec");
                    password = decodeURIComponent(password);
                } catch (e) {
                    
                }
                if (password) {  
                    
                    Prefs.prefBranch.clearUserPref("mastersec");
                    
                    this.setMasterPwd(password);
                }
            }
            return password;
        },


        
        setMasterPwd(password) {
            var nsLoginInfo = new Components.
                Constructor("@mozilla.org/login-manager/loginInfo;1",
                            Ci.nsILoginInfo, "init");
            let new_login = new nsLoginInfo(iMacros_auth_host, 
                                            iMacros_auth_desc,
                                            null, "master", password, "", "");
            var logins = Services.logins.findLogins({}, iMacros_auth_host,
                                                    iMacros_auth_desc, null);
            for (let login of logins) {
                if (login.username == "master") {
                    Services.logins.modifyLogin(login, new_login);
                    return;
                }
            }
            Services.logins.addLogin(new_login);
        },

        
        
        __session_password: null,

        
        getSessionPwd() {
            return this.__session_password;
        },


        
        setSessionPwd(password) {
            this.__session_password = password;
        },

        
        get encryptionType() {
            let type = this.TYPE_NONE;
            try {
                type = Prefs.encryptionType;
            } catch (e) {
                
                Prefs.encryptionType = this.TYPE_NONE;
            }

            return type;
        },

        set encryptionType(typ) {
            switch (typ) {
            case this.TYPE_NONE: case this.TYPE_STORED: case this.TYPE_TEMP:
                Prefs.encryptionType = typ;
                break;
            default:
                Prefs.encryptionType = this.TYPE_NONE;
                break;
            }
        },

        
        get TYPE_NONE()   { return 1; },
        get TYPE_STORED() { return 2; },
        get TYPE_TEMP()   { return 3; },

        
        
        enquireLoginManager(user) {
            let logins = Services.logins.findLogins({}, iMacros_auth_host,
                                                    iMacros_auth_desc, null);
            for (let login of logins) {
                if (login.username == user) {
                    return login.password;
                }
            }
            return null;
        },

        getEncryptionKey() {
            let key = "";
            if (this.encryptionType == this.TYPE_NONE) {
                return "";
            } else if (this.encryptionType == this.TYPE_STORED) {
                key = this.getMasterPwd();
            } else if (this.encryptionType == this.TYPE_TEMP) {
                key = this.getSessionPwd();
            }

            if (!key) {
                const msg = "Please enter your ecnryption password:";
                const check_msg = "Use this password as Master password";
                let param = {value: null};
                let check = {value: pm.encryptionType == pm.TYPE_STORED};
                let ok = Services.prompt.promptPassword(
                    MiscUtils.browserWindow, "iMacros", msg,
                    param, check_msg, check
                );
                if (!ok) 
                    throw new Error("User cancelled password dialog");

                key = param.value;
                if (check.value) {
                    this.setMasterPwd(key);
                    this.encryptionType = this.TYPE_STORED;
                } else {
                    this.setSessionPwd(key);
                    this.encryptionType = this.TYPE_TEMP;
                }
            }
            
            return key;
        }
    };
})();
